using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace HalconDotNet
{
	internal class HTupleInt64 : HTupleImplementation
	{
		protected long[] l;

		public override long[] LArr
		{
			get
			{
				return l;
			}
			set
			{
				SetArray(value, copy: false);
			}
		}

		public override HTupleType Type => HTupleType.LONG;

		protected override Array CreateArray(int size)
		{
			return new long[size];
		}

		protected override void NotifyArrayUpdate()
		{
			l = (long[])data;
		}

		internal override void PinTuple()
		{
			Monitor.Enter(this);
			if (pinCount == 0)
			{
				pinHandle = GCHandle.Alloc(l, GCHandleType.Pinned);
			}
			pinCount++;
			Monitor.Exit(this);
		}

		public HTupleInt64(long l)
		{
			SetArray(new long[1]
			{
				l
			}, copy: false);
		}

		public HTupleInt64(long[] l, bool copy)
		{
			SetArray(l, copy);
		}

		public override HTupleElements GetElement(int index, HTuple parent)
		{
			return new HTupleElements(parent, this, index);
		}

		public override HTupleElements GetElements(int[] indices, HTuple parent)
		{
			if (indices == null || indices.Length == 0)
			{
				return new HTupleElements();
			}
			return new HTupleElements(parent, this, indices);
		}

		public override void SetElements(int[] indices, HTupleElements elements)
		{
			HTupleElementsInt64 hTupleElementsInt = new HTupleElementsInt64(this, indices);
			hTupleElementsInt.setL(elements.LArr);
		}

		public override int[] ToIArr()
		{
			int[] array = new int[iLength];
			for (int i = 0; i < iLength; i++)
			{
				array[i] = (int)l[i];
			}
			return array;
		}

		public override long[] ToLArr()
		{
			return (long[])ToArray(typeL);
		}

		public override double[] ToDArr()
		{
			return (double[])ToArray(typeD);
		}

		public override float[] ToFArr()
		{
			return (float[])ToArray(typeF);
		}

		public override IntPtr[] ToIPArr()
		{
			if (!HalconAPI.isPlatform64)
			{
				base.ToIPArr();
			}
			IntPtr[] array = new IntPtr[iLength];
			for (int i = 0; i < iLength; i++)
			{
				array[i] = new IntPtr(l[i]);
			}
			return array;
		}

		public override int CopyToLArr(long[] dst, int offset)
		{
			Array.Copy(l, 0, dst, offset, iLength);
			return iLength;
		}

		public override int CopyToOArr(object[] dst, int offset)
		{
			for (int i = 0; i < iLength; i++)
			{
				dst[i + offset] = l[i];
			}
			return iLength;
		}

		public override int CopyFrom(HTupleImplementation impl, int offset)
		{
			return impl.CopyToLArr(l, offset);
		}

		public override void Store(IntPtr proc, int parIndex)
		{
			HalconAPI.HCkP(proc, HalconAPI.GetInputTuple(proc, parIndex, out IntPtr tuple));
			StoreData(proc, tuple);
		}

		protected override void StoreData(IntPtr proc, IntPtr tuple)
		{
			PinTuple();
			if (!HalconAPI.isPlatform64)
			{
				HalconAPI.HCkP(proc, HalconAPI.CreateElementsOfType(tuple, base.Length, HTupleType.INTEGER));
				for (int i = 0; i < base.Length; i++)
				{
					HalconAPI.SetL(tuple, i, l[i]);
				}
			}
			else
			{
				HalconAPI.SetLArrPtr(tuple, l, iLength);
			}
		}

		public static int Load(IntPtr tuple, out HTupleInt64 data)
		{
			HalconAPI.GetTupleLength(tuple, out int length);
			long[] longArray = new long[length];
			int lArr = HalconAPI.GetLArr(tuple, longArray);
			data = new HTupleInt64(longArray, copy: false);
			return lArr;
		}
	}
}
